import path from "path";
import { CreateDist, DistStruct } from "../../common/src/CreateDist";
import { Assemble } from "./Assemble";
import { Decode } from "./Decode";
import { WebsocketServer } from "./Server";
import { delDir } from "../../common/src/utils/dir";
import fs from "fs";
import { Resources } from "./Resources";
import { ComponentFolder } from "../../common/domain/ComponentFoder";
import { UseComponent } from "./UseComponent";
import { PackResult } from "./Download";

export interface componentNickname {
  componentId: string;
  componentName: string;
}

export class Main {
  wsServer: WebsocketServer;
  decoder: Decode | undefined;
  component: componentNickname[] = [];
  dist: DistStruct | null = null;
  template: CreateDist;
  projectRoot: string = "";
  res: Resources | null = null;
  cf: ComponentFolder;

  uc: UseComponent
  constructor(projectRoot: string) {
    this.projectRoot = projectRoot;
    this.cf = new ComponentFolder(this.projectRoot);
    // this.dist = new CreateDist(this.projectRoot, "result").getDistStructure();
    this.template = new CreateDist(this.projectRoot, "result", true);
    this.dist = this.template.getDistStructure();
    this.uc = new UseComponent(this.projectRoot);

    this.wsServer = new WebsocketServer((obj, con) => {
      const msg = obj.msg
      const pos = msg.indexOf("|");
      const handleName: string = msg.substring(0, pos);
      // console.log(handleName, "handleName");
      const p = msg.substring(pos + 1)

      switch (handleName) {
        case "download":
          const ps = new PackResult(this.projectRoot)
          ps.pack().then(() => {
            con.send(JSON.stringify({
              data: "over",
              handleKey: obj.handleKey
            }))
            // new Response(p, con).sendStr("over")
          })
          break;
        case "clearPreview":
          this.uc.run("clearPreview", { rootPath: this.projectRoot })
          this.clear()
          con.send(JSON.stringify({
            data: "清空完成",
            handleKey: obj.handleKey
          }))
          break;
        case "useComponent":
          this.uc.run("useComponent", { rootPath: this.projectRoot, componentName: p })
          con.send(JSON.stringify({
            data: "模块添加成功",
            handleKey: obj.handleKey
          }))
          break;
        case "decode":
          this.decoder = new Decode(p);
          this.assemble().then(() => {
            // this.clear();
            this.removeDev();
            // console.log(this.decoder?.getStyle());
          });
          break;
        case "sync":
          // console.log("receive sync:", p);
          // this.component.push(JSON.parse(p));
          this.clear()
          this.component = JSON.parse(p);
          break;
        case "resources":
          this.res = new Resources(p);
          break;
        // case "clear":
        //   this.clear();
        //   break;
        // case "hotReload":
        //   this.hotReload();
        //   break;
        default:
          if (!handleName.startsWith("upload>")) break;
          let fileName = handleName.substring(7, handleName.length);
          if (!this.dist) {
            console.log("error: cannot load dist structure", fileName);
            return;
          }
          if (fileName === "newImg.png") {
            fileName =
              fs.readdirSync(this.dist.getImgFolderPath()).length + 1 + ".png";
            // fileName.substring(fileName.indexOf("."));
          } else {
            // if (this.res)
            // require resources...
            fileName = path.basename(fileName);
            // else console.log("error: cannot parse resources!");
          }
          // console.log(fileName, "upload file name", handleName);

          const to = path.join(this.dist.getImgFolderPath(), fileName);
          // console.log(to, "to");

          const data = msg.substring(pos + 1);

          // console.log(data.substring(0, 100), "data");

          fs.writeFileSync(
            to,
            data.replace(/^data:image\/\w+;base64,/, ""),
            "base64"
          );

          break;
      }
    });
  }
  public clear() {
    this.component = [];
    this.decoder?.clear();
    this.dist = new CreateDist(this.projectRoot, "result", true).getDistStructure();
  }

  public async assemble() {
    if (!this.decoder) throw Error("decoder does not exist!");
    if (!this.dist) {
      console.log("error: cannot load folder structure");
      return;
    }
    if (!this.res) {
      console.log("error: resources not load!");
      return;
    }
    const ass = new Assemble(
      this.projectRoot,
      this.component,
      this.dist,
      this.decoder,
      this.res
    );

    // console.log("ass");

    await ass.load(this.cf);
  }
  // private hotReload() {
  //   this.template.reloadIndex();
  // }
  private removeDev() {
    if (!this.dist) throw Error("cannot get dist structure");
    const devFolder = path.join(this.dist.getRootPath(), "dev");
    if (fs.existsSync(devFolder)) delDir(devFolder);
  }
  beautify() { }
}
